package com.free.mysql;

import java.util.List;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.free.freemarker.constant.Constant;
import com.free.freemarker.core.Builder;
import com.free.freemarker.module.Model;
import com.free.freemarker.manager.Manager;
import com.free.freemarker.utils.StringUtil;
import com.free.mysql.model.Column;
import com.free.mysql.model.Idx;
import com.free.mysql.model.Table;

/**
 * @author liuhuan
 */
public class MyBuilder implements Builder {

    private Manager manager;
    private String tableName;
    private String className;
    private String classNameLower;
    private String modelURL;
    private String daoURL;
    private String daoImplURL;
    private String serviceURL;
    private String serviceImplURL;
    private String controllerURL;
    private String description;
    private Table table;
    private Model model;

    @Override
    public void builder(Manager manager, String tableName, String description)
            throws Exception {
        this.manager = manager;
        this.tableName = tableName;
        this.description = description;
        model = new Model();

        dealTable(Constant.TABLE_PREFIX);
        dealURL();
        builderDataModel();

        JSONArray jja = Constant.JAVA_FTL;
        if (jja != null) {
            for (int i = 0; i < jja.size(); i++) {
                JSONObject j = jja.getJSONObject(i);
                String ftl = j.getString("ftl");
                String rule = j.getString("name");
                builderMybatisJava(rule, ftl);
            }
        }

        JSONObject jj = Constant.Mybatis_FTL;
        if (jj != null) {
            String ftl = jj.getString("ftl");
            String rule = jj.getString("name");
            builderMybatisXML(rule, ftl);
        }

        JSONArray HS = Constant.VIEW_FTL;
        if (HS != null) {
            for (int i = 0; i < HS.size(); i++) {
                JSONArray ja = HS.getJSONArray(i);
                builderWeb(ja.getString(0), ja.getString(1));
            }
        }
    }

    /**
     * 生成
     */
    public void builderMybatisJava(String rule, String templateName)
            throws Exception {
        String className = (String) model.get(Constant.CLASS_NAME_VAR);
        className = String.format(rule, className);
        manager.builder(Constant.filePath, className, Constant.SUFFIX, templateName, model);
    }

    public void builderMybatisXML(String rule, String templateName) throws Exception {
        String tableNameLower = (String) model.get(Constant.CLASS_NAME_LOWER_VAR);
        tableNameLower = String.format(rule, tableNameLower);
        manager.builder(Constant.filePath, tableNameLower, ".xml", templateName, model);
    }

    public void builderWeb(String templateName, String suffix) throws Exception {
        String name = classNameLower + "_" + templateName.substring(0, templateName.indexOf("."));
        manager.builder(Constant.filePath, name, "." + suffix, templateName, model);
    }


    @Override
    public void builderDataModel() throws Exception {
        model = Model.builder(manager.getSqlBuilder());
        table = model.rootTableBuilder(tableName);
        List<Idx> idxList = table.getIdxList();
        Idx idx;
        for (int i = 0, len = idxList.size(); i < len; i++) {
            idx = idxList.get(i);
            idx.getIdxName();
        }

        modelBuilder();
        daoBuilder();
        serviceBuilder();
        serviceImplBuilder();
        controllerBuilder();
        buildHTML();
    }


    public void modelBuilder() {
        model.put(MyConstant.MODEL_URL_VAR, modelURL);
        model.put(MyConstant.DAO_URL_VAR, daoURL);
        model.put(MyConstant.DAO_IMPL_URL_VAR, daoURL);
        model.put(MyConstant.SERVICE_URL_VAR, serviceURL);
        model.put(MyConstant.SERVICE_IMPL_URL_VAR, serviceImplURL);
        model.put(MyConstant.CONTROLLER_URL_VAR, controllerURL);


        model.put(Constant.CLASS_NAME_VAR, className);
        model.put(Constant.CLASS_NAME_LOWER_VAR, classNameLower);
        model.put(Constant.TABLE_NAME,tableName);


        List<Column> colList = table.getColumnList();
        List<Idx> idxList = table.getIdxList();
        model.put(Constant.IDX_LIST_VAR, idxList);

        // 表列信息
        model.put(Constant.COL_LIST_VAR, colList);
        model.put(Constant.DESCRIPTION_VAR, description);

        // 包名
        model.put(Constant.M_PACKAGE_NAME_VAR, modelURL.substring(0, modelURL.lastIndexOf(".")));
        model.put(Constant.M_CLASS_PATH_VAR, modelURL);
    }

    public void daoBuilder() {
        model.put(Constant.D_PACKAGE_NAME_VAR, daoURL.substring(0, daoURL.lastIndexOf(".")));
        model.put(Constant.D_CLASS_NAME_SUFFIX_VAR, MyConstant.DAO_SUFFIX);

        String name = daoURL.substring(daoURL.lastIndexOf(".") + 1, daoURL.length());
        model.put(Constant.D_CLASS_NAME_VAR, name);
        model.put(Constant.D_CLASS_NAME_LVAR, StringUtil.firstLower(name));


        model.put(Constant.DL_PACKAGE_NAME_VAR, daoImplURL.substring(0, daoImplURL.lastIndexOf(".")));
        model.put(Constant.DL_CLASS_NAME_SUFFIX_VAR, MyConstant.DAO_IMPL_SUFFIX);

        name = daoImplURL.substring(daoImplURL.lastIndexOf(".") + 1, daoImplURL.length());
        model.put(Constant.DL_CLASS_NAME_VAR, name);
    }

    public void serviceBuilder() throws Exception {
        model.put(Constant.S_PACKAGE_NAME_VAR, serviceURL.substring(0, serviceURL.lastIndexOf(".")));

        model.put(Constant.S_CLASS_NAME_PREFIX_VAR, MyConstant.SERVICE_PREFIX);
        model.put(Constant.S_CLASS_NAME_SUFFIX_VAR, MyConstant.SERVICE_SUFFIX);

        String name = serviceURL.substring(serviceURL.lastIndexOf(".") + 1, serviceURL.length());
        model.put(Constant.S_CLASS_NAME_VAR, name);
        model.put(Constant.S_CLASS_NAME_LVAR, StringUtil.firstLower(name));

    }

    public void serviceImplBuilder() throws Exception {
        model.put(Constant.SL_PACKAGE_NAME_VAR, serviceImplURL.substring(0, serviceImplURL.lastIndexOf(".")));
        model.put(Constant.SL_CLASS_NAME_SUFFIX_VAR, MyConstant.SERVICE_IMPL_SUFFIX);

        String name = serviceImplURL.substring(serviceImplURL.lastIndexOf(".") + 1, serviceImplURL.length());
        model.put(Constant.SL_CLASS_NAME_VAR, name);
    }


    public void controllerBuilder() throws Exception {
        // 包名
        model.put(Constant.C_PACKAGE_NAME_VAR, controllerURL.substring(0, controllerURL.lastIndexOf(".")));
        // 类名后缀
        model.put(Constant.C_CLASS_NAME_SUFFIX_VAR, MyConstant.CONTROLLER_SUFFIX);

        String name = controllerURL.substring(controllerURL.lastIndexOf(".") + 1, controllerURL.length());
        model.put(Constant.C_CLASS_NAME_VAR, name);
    }

    public void buildHTML() {
    }

    @Override
    public void dealTable(String prefix) {
        String str = tableName.substring(prefix.length());
        className = StringUtil.hump(str);
        classNameLower = StringUtil.firstLower(className);
    }

    @Override
    public void dealURL() {
        modelURL = String.format(MyConstant.PACKAGE_BASE_URL + "." + MyConstant.ENTITY_BASE_URL, className);

        daoURL = String.format(MyConstant.PACKAGE_BASE_URL + "." + MyConstant.DAO_BASE_URL, className + MyConstant.DAO_SUFFIX);

        daoImplURL = String.format(MyConstant.PACKAGE_BASE_URL + "." + MyConstant.DAO_IMPL_BASE_URL, className + MyConstant.DAO_IMPL_SUFFIX);

        serviceURL = String.format(MyConstant.PACKAGE_BASE_URL + "." + MyConstant.SERVICE_BASE_URL, MyConstant.SERVICE_PREFIX + className + MyConstant.SERVICE_SUFFIX);

        serviceImplURL = String.format(MyConstant.PACKAGE_BASE_URL + "." + MyConstant.SERVICE_IMPL_BASE_URL, className + MyConstant.SERVICE_IMPL_SUFFIX);

        controllerURL = String.format(MyConstant.PACKAGE_BASE_URL + "." + MyConstant.CONTROLLER_BASE_URL, className + MyConstant.CONTROLLER_SUFFIX);

    }
}
